using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace Microsoft.VSPowerToys.PackInstaller
{
    public partial class TagItemControl : UserControl
    {
        /// <summary>
        /// Raised when user selects the tag
        /// </summary>
        public event EventHandler<TagSelectedEventArgs> TagSelected;

        private string tagName;

        /// <summary>
        /// Property to hold the string that is the name of the tag.
        /// </summary>
        public string TagName
        {
            get { return this.tagName; }
            set 
            { 
                this.tagName = value;
                this.tagNameLabel.Text = this.tagName;
            }
        }

        private int tagCount;

        /// <summary>
        /// Property to hold the count for this tag.
        /// </summary>
        public int TagCount
        {
            get { return this.tagCount; }
            set 
            {
                this.tagCount = value;
                this.tagCountLabel.Text = this.tagCount.ToString(Application.CurrentCulture.NumberFormat);
            }
        }

        /// <summary>
        /// This enum represents whether the tag is currently selected, the mouse is over it, or nothing.
        /// </summary>
        public enum TagState
        {
            None,
            Hovered,
            Selected
        }

        private TagState currentTagState;

        /// <summary>
        /// This property holds the current state for drawing.
        /// </summary>
        public TagState CurrentTagState
        {
            get { return this.currentTagState; }
            set { SetSelectionState(value); }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public TagItemControl() : this(Strings.UnassignedTagName)
        {
        }

        /// <summary>
        /// Constructor, initializes the tag name and fonts.
        /// </summary>
        public TagItemControl(string tagName)
        {
            this.tagName = tagName;
            InitializeComponent();
            this.Font = SystemFonts.DialogFont;
            this.tagNameLabel.Text = tagName;
        }

        /// <summary>
        /// Method to set the selection to a particular value, and then refresh the control.
        /// </summary>
        private void SetSelectionState(TagState selectionState)
        {
            this.currentTagState = selectionState;
            this.Refresh();
        }

        /// <summary>
        /// Selects the tag, and propagates an event.
        /// </summary>
        public void SelectTag()
        {
            if (this.currentTagState != TagState.Selected)
            {
                this.currentTagState = TagState.Selected;
                this.Refresh();
            }

            if (TagSelected != null)
            {
                TagSelected(this, new TagSelectedEventArgs(this.tagName));
            }
        }

        /// <summary>
        /// Event raised when the tag is selected by the user.
        /// </summary>
        private void tagNameLabel_Click(object sender, EventArgs e)
        {
            SelectTag();
        }

        /// <summary>
        /// Event triggered when the mouse moves over the label, we want this to change the drawing state.
        /// </summary>
        private void tagNameLabel_MouseEnter(object sender, EventArgs e)
        {
            if (this.currentTagState != TagState.Selected)
            {
                this.currentTagState = TagState.Hovered;
                this.Refresh();
            }
        }

        /// <summary>
        /// Event triggered when the mouse moves off the label, we want this to change the drawing state.
        /// </summary>
        private void tagNameLabel_MouseLeave(object sender, EventArgs e)
        {
            if (this.currentTagState != TagState.Selected)
            {
                this.currentTagState = TagState.None;
                this.Refresh();
            }
        }

        /// <summary>
        /// In the paint event we want to draw the little indicator next to the name of the tag if the mouse is
        /// hovering, or the tag is currently selected.
        /// For small sizes using the drawing commands was resulting in better indicators than using a pre-canned bitmap.
        /// It also scales better up in size if necessary.
        /// </summary>
        private void tagSelectedPictureBox_Paint(object sender, PaintEventArgs e)
        {
            if (this.currentTagState != TagState.None)
            {
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

                Rectangle fillRectangle = new Rectangle(this.tagSelectedPictureBox.ClientRectangle.Location, this.tagSelectedPictureBox.ClientRectangle.Size);
                if (fillRectangle.Width > fillRectangle.Height)
                {
                    int diff = fillRectangle.Width - fillRectangle.Height;
                    fillRectangle.Location = new Point(fillRectangle.Location.X + (diff / 2), fillRectangle.Location.Y);
                    fillRectangle.Width = fillRectangle.Height;
                }
                else
                {
                    int diff = fillRectangle.Height - fillRectangle.Width;
                    fillRectangle.Location = new Point(fillRectangle.Location.X, fillRectangle.Location.Y + (diff / 2));
                    fillRectangle.Height = fillRectangle.Width;
                }

                fillRectangle.Width = fillRectangle.Width - 1;
                fillRectangle.Height = fillRectangle.Height - 1;

                GraphicsPath newPath = new GraphicsPath();
                newPath.AddEllipse(fillRectangle);

                PathGradientBrush pathPaintBrush = new PathGradientBrush(newPath);
                
                ColorBlend gradientBlend = new ColorBlend(2);
                gradientBlend.Positions[0] = 0.0f;
                gradientBlend.Positions[1] = 1.0f;

                bool drawOutline;

                if (this.Enabled)
                {
                    drawOutline = true;
                    if (this.currentTagState == TagState.Hovered)
                    {
                        gradientBlend.Colors[1] = Color.LightGray;
                        gradientBlend.Colors[0] = Color.Gray;
                    }
                    else
                    {
                        gradientBlend.Colors[1] = Color.LightBlue;
                        gradientBlend.Colors[0] = Color.Blue;
                    }
                }
                else
                {
                    drawOutline = false;
                    gradientBlend.Colors[1] = SystemColors.GradientInactiveCaption;
                    gradientBlend.Colors[0] = SystemColors.GrayText;
                    
                }

                pathPaintBrush.InterpolationColors = gradientBlend;

                e.Graphics.FillEllipse(pathPaintBrush, fillRectangle);
                if (drawOutline)
                {
                    e.Graphics.DrawEllipse(Pens.Black, fillRectangle);
                }
            }
        }
    }

    /// <summary>
    /// An event arguments class for the event raised when the user clicks on the name of the tag.
    /// </summary>
    public class TagSelectedEventArgs : EventArgs
    {
        [NonSerialized]
        private string tagName;

        public string TagName
        {
            get { return this.tagName; }
            set { this.tagName = value; }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="task">Task that owns the event</param>
        public TagSelectedEventArgs(string tagName)
        {
            this.tagName = tagName;
        }
    }

}
